import { iframeSDK, postMsgUtil, requestSDK } from "@ct/iframe-connect-sdk";
import $ from "jquery";
import request from "@/utils/new-axios";
import { Loading, Message, Notification } from "element-ui";
import { $cookie, $session, $store } from "@/utils/store";
import { getUserMemoryInfo } from "@/api/common";
import { getMessageHtml } from "@/utils/popMessage";

/**
 * 通用js方法封装
 */
export const PAGE_SIZES = [10, 20, 50, 100];
export const PAGE_SIZE = PAGE_SIZES[0]; // 分页中的每页条数
export const urlSystem = "community-system";
export const urlBigscren = "community-bigscreen";
export const urlBaseService = "community-base";

export const urlImg = process.env.VUE_APP_BASE_IMG;
const baseURL = process.env.VUE_APP_BASE_API;
const baserServerUrl = process.env.VUE_APP_BASE_SERVER_API;
export const amapKey = "e1fb9ce1bfa5beacb0187e93b2181661"; // 高德地图key

$(function () {
  // 开启全局监听
  registerSocket();
  ejectMsg();
  listenMsgTab();
});

/** 将数字格式化逢三一断 */
export function numberFormat(value) {
  let result = "0";
  let valstr = "";
  let fixed = "";
  if (value && value > 0) {
    valstr = value.toString();
    if (valstr.indexOf(".") > -1) {
      fixed = valstr.substring(valstr.indexOf("."), valstr.length);
      valstr = valstr.substring(0, valstr.indexOf("."));
    }
    result = valstr.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,") + fixed;
  }
  return result;
}

/** 对象属性合成 */
export function extend() {
  const length = arguments.length;
  let target = arguments[0] || {};
  if (typeof target !== "object" && typeof target !== "function") {
    target = {};
  }
  let i = 1;
  if (length === 1) {
    target = this;
    i--;
  }
  for (i; i < length; i++) {
    const source = arguments[i];
    for (const key in source) {
      // 使用for in会遍历数组所有的可枚举属性，包括原型。
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        target[key] = source[key];
      }
    }
  }
  return target;
}

export const verifyRules = {
  required: { required: true, message: "必填项", trigger: ["blur", "change"] },
  phone: {
    pattern: /^1[0-9]{10}$/,
    message: "请输入正确的手机号码",
    trigger: "blur",
  },
  email: { type: "email", message: "请输入正确的邮箱地址", trigger: "blur" },
  Abc: { pattern: /^[A-Za-z]+$/, message: "只能输入字母", trigger: "blur" },
  ABC: { pattern: /^[A-Z]+$/, message: "只能输入大写字母", trigger: "blur" },
  abc: { pattern: /^[a-z]+$/, message: "只能输入小写字母", trigger: "blur" },
  noCN: {
    pattern: /^[A-Za-z0-9]+$/,
    message: "只能输入数字、字母",
    trigger: "blur",
  },
  sixNum: { pattern: /^\d{6}$/, message: "请输入6位数字", trigger: "blur" },
  int: {
    pattern: /^(0|\+?[1-9][0-9]*)$/,
    message: "只能输入非负整数",
    trigger: "blur",
  },
  zInt: {
    pattern: /^(\+?[1-9][0-9]*)$/,
    message: "只能输入正整数",
    trigger: "blur",
  },
  url: {
    pattern: /^(http(s?)|):\/\/(.+)$/,
    message: "请输入正确的链接地址",
    trigger: "blur",
  },
  float: {
    pattern: /^(([1-9]\d*)|(0))(\.\d{1,2})?$/,
    message: "只能输入非负数，且最多保留两位小数",
    trigger: "blur",
  },
  idCard: {
    pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
    message: "请输入正确的身份证号",
    trigger: "blur",
  },
  longitude: {
    pattern:
      /^([-+])?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,6})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,6}|180)$/,
    message: "经度整数部分为-180到180,小数部分为0到6位",
    trigger: "blur",
    required: true,
  },
  latitude: {
    pattern: /^([-+])?([0-8]?\d\.\d{0,6}|90\.0{0,6}|[0-8]?\d|90)$/,
    message: "纬度整数部分为-90到90,小数部分为0到6位",
    trigger: "blur",
    required: true,
  },
  account: {
    pattern: /^[a-zA-Z0-9_-]{4,16}$/,
    message: "账号必须为4-16位(字母/数字/下划线/减号)",
    trigger: "blur",
  },
  password: {
    pattern: /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,20}$/,
    message: "密码必须为字母、数字和特殊符号组成的8-20位字符",
    trigger: "blur",
  },
  creditCode: {
    pattern: /^[a-zA-Z0-9]{18}$/,
    message: "请输入字母和数字组成的18位字符",
    trigger: "blur",
  },
  height: {
    pattern: /^[1-9]\d*(\.\d+)?$|^0\.\d*[1-9]\d*$/,
    message: "设备挂高为大于0的数值",
    trigger: "blur",
    required: true,
  },
  groundHeight: {
    pattern: /^[1-9]\d*(\.\d+)?$|^0\.\d*[1-9]\d*$/,
    message: "海拔为大于0的数值",
    trigger: "blur",
    required: true,
  },
  visionDistance: {
    pattern: /^[1-9]\d*(\.\d+)?$|^0\.\d*[1-9]\d*$/,
    message: "视野距离为大于0的数值",
    trigger: "blur",
    required: true,
  },
  horizontalAngle: {
    pattern:
      /^1\.\d*|^[2-9](\.\d+)?$|^[1]\d(\.\d+)?$|^[2-9]\d?(\.\d+)?$|^1[0-1]\d(\.\d+)?$/,
    message: "水平视角为大于1且小于120的数值",
    trigger: "blur",
    required: true,
  },
  verticalAngle: {
    pattern: /^15\.\d*|^1[6-9](\.\d+)?$|^[2-9]\d(\.\d+)?$|^1[0-1]\d(\.\d+)?$/,
    message: "垂直视角为大于15且小于120的数值",
    trigger: "blur",
    required: true,
  },
  direction: {
    pattern:
      /^0\.\d*[1-9]\d*|^[1-9]\d?(\.\d+)?$|^[1-2]\d{2}(\.\d+)?$|^3[0-5]\d(\.\d+)?$/,
    message: "方向角大于0且小于或等于360的数值",
    trigger: "blur",
    required: true,
  },
  pitch: {
    pattern: /^-?(90|[0-8]?\d?(\.\d+)?)$/,
    message: "俯仰角为-90到90的数值",
    trigger: "blur",
    required: true,
  },
};

/** 通用表单校验规则 */
export function getRules() {
  const length = arguments.length;
  if (length === 0) {
    return {};
  }
  const isRequired = !!arguments[0];
  if (length > 1) {
    const rules = [];
    rules.push({
      required: isRequired,
      message: "必填项",
      trigger: ["blur", "change"],
    });
    for (let i = 1; i < length; i++) {
      rules.push(verifyRules[arguments[i]]);
    }
    return rules;
  } else {
    return {
      required: isRequired,
      message: "必填项",
      trigger: ["blur", "change"],
    };
  }
}

/** 精确身份证号码校验 */
export function validateIDCardExact(rule, idcode, callback) {
  const weight_factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; // 加权因子
  const check_code = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"]; // 校验码
  const code = idcode + "";
  const last = idcode[17]; // 最后一位
  const seventeen = code.substring(0, 17);
  // ISO 7064:1983.MOD 11-2 判断最后一位校验码是否正确
  const arr = seventeen.split("");
  const len = arr.length;
  let num = 0;
  for (let i = 0; i < len; i++) {
    num = num + arr[i] * weight_factor[i];
  }
  const last_no = check_code[num % 11]; // 获取余数
  /**
   *格式的正则 正则思路：第一位不可能是0;第二位到第六位可以是0-9
   *第七位到第十位是年份，所以七八位为19或者20;十一位和十二位是月份，这两位是01-12之间的数值;十三位和十四位是日期，是从01-31之间的数值;
   *第十五，十六，十七都是数字0-9;十八位可能是数字0-9，也可能是X
   */
  const idcard_patter =
    /^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0|1][0-9])([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[X])$/;
  // 返回验证结果，校验码和格式同时正确才算是合法的身份证号码
  if (last === last_no && idcard_patter.test(idcode)) {
    callback();
  } else {
    callback(new Error("请输入正确的身份证号"));
  }
}

export function formateTime(time) {
  if (typeof time === "string" && /^[0-9]+$/.test(time)) {
    time = parseInt(time);
  }
  if (typeof time === "number" && time.toString().length === 10) {
    time = time * 1000;
  }
  return time;
}

/** 日期时间格式化 */
export function parseTime(time, pattern) {
  if (time == null || time === "" || arguments.length === 0) {
    return "";
  }
  let date;
  if (typeof time === "object") {
    date = time;
  } else {
    date = new Date(formateTime(time));
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };

  const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
  return format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key];
    if (key === "a") {
      return ["日", "一", "二", "三", "四", "五", "六"][value];
    }
    if (result.length > 0 && value < 10) {
      value = "0" + value;
    }
    return value || 0;
  });
}
/** 表格时间格式化 */
export function tableTimeFormat(row, column, cellValue, index) {
  return parseTime(cellValue, "{y}-{m}-{d} {h}:{i}:{s}");
}
/** 表格日期格式化 */
export function tableDateFormat(row, column, cellValue, index) {
  return parseTime(cellValue, "{y}-{m}-{d}");
}
/** 数据字典列表转为字典格式化方法列表 */
export function dictToFormatters(dicts, formatters) {
  Object.keys(dicts).forEach((key) => {
    formatters[key] = (row, column, cellValue, index) => {
      return this.selectDictLabel(dicts[key], cellValue);
    };
  });
}
/** 表单重置 */
export function resetForm(refName) {
  if (this.$refs[refName]) {
    const fields = this.$refs[refName].fields;
    if (fields.length > 0) {
      fields.forEach((field) => {
        if (field.$children.length > 1 && !field.$children[1].disabled) {
          field.resetField();
        }
      });
    }
  }
}

/** 添加日期范围 */
export function addDateRange(params, dateRange) {
  var search = params;
  search.beginTime = "";
  search.endTime = "";
  if (dateRange != null && dateRange !== "") {
    search.beginTime = dateRange[0];
    search.endTime = dateRange[1];
  }
  return search;
}

/** 回显数据字典 */
export function selectDictLabel(datas, value) {
  value = "" + value;
  if (datas && value) {
    var actions = [];
    Object.keys(datas).map((key) => {
      if (datas[key].dictValue === value) {
        actions.push(datas[key].dictLabel);
        return false;
      }
    });
    return actions.join("");
  }
  return "";
}

/** 通用下载方法 */
export function download(fileName) {
  window.location.href =
    baseURL +
    "/admin/base/common/download/name?fileName=" +
    encodeURI(fileName) +
    "&delete=" +
    true;
}

/** 字符串格式化(%s ) */
export function sprintf(str) {
  var args = arguments;
  var flag = true;
  var i = 1;
  str = str.replace(/%s/g, function () {
    var arg = args[i++];
    if (typeof arg === "undefined") {
      flag = false;
      return "";
    }
    return arg;
  });
  return flag ? str : "";
}

/** 转换字符串，undefined,null等转化为""  */
export function praseStrEmpty(str) {
  if (!str || str === "undefined" || str === "null") {
    return "";
  }
  return str;
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (("" + time).length === 10) {
    time = parseInt(time) * 1000;
  } else {
    time = +time;
  }
  const d = new Date(time);
  const now = Date.now();
  const diff = (now - d) / 1000;
  if (diff < 30) {
    return "刚刚";
  } else if (diff < 3600) {
    return Math.ceil(diff / 60) + "分钟前";
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + "小时前";
  } else if (diff < 3600 * 24 * 2) {
    return "1天前";
  } else {
    if (option) {
      return parseTime(time, option);
    } else {
      return (
        d.getMonth() +
        1 +
        "月" +
        d.getDate() +
        "日" +
        d.getHours() +
        "时" +
        d.getMinutes() +
        "分"
      );
    }
  }
}

/**
 * 秒转为天数小时分钟秒
 * @param {*} msd
 * @returns
 */
export function secondToDate(msd) {
  var time = msd;
  if (time != null && time != "") {
    if (time > 60 && time < 60 * 60) {
      time =
        parseInt(time / 60.0) +
        "分钟" +
        parseInt((parseFloat(time / 60.0) - parseInt(time / 60.0)) * 60) +
        "秒";
    } else if (time >= 60 * 60 && time < 60 * 60 * 24) {
      time =
        parseInt(time / 3600.0) +
        "小时" +
        parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) +
        "分钟" +
        parseInt(
          (parseFloat(
            (parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60
          ) -
            parseInt(
              (parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60
            )) *
            60
        ) +
        "秒";
    } else if (time >= 60 * 60 * 24) {
      time =
        parseInt(time / 3600.0 / 24) +
        "天" +
        parseInt(
          (parseFloat(time / 3600.0 / 24) - parseInt(time / 3600.0 / 24)) * 24
        ) +
        "小时" +
        parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) +
        "分钟" +
        parseInt(
          (parseFloat(
            (parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60
          ) -
            parseInt(
              (parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60
            )) *
            60
        ) +
        "秒";
    } else {
      time = parseInt(time) + "秒";
    }
  }
  return time;
}

export function getExecStrs(str) {
  const reg = /#\{(.+?)\}/g;
  const list = [];
  let result = null;
  do {
    result = reg.exec(str);
    result && list.push(result[1]);
  } while (result);
  return list;
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url) {
  url = url == null ? window.location.href : url;
  const search = url.substring(url.lastIndexOf("?") + 1);
  const obj = {};
  const reg = /([^?&=]+)=([^?&=]*)/g;
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1);
    let val = decodeURIComponent($2);
    val = String(val);
    obj[name] = val;
    return rs;
  });
  return obj;
}

/**
 * 返回utf8字符串的字节长度
 * @param {string} input value
 * @returns {number} output value
 */
export function byteLength(str) {
  let s = str.length;
  for (var i = str.length - 1; i >= 0; i--) {
    const code = str.charCodeAt(i);
    if (code > 0x7f && code <= 0x7ff) {
      s++;
    } else if (code > 0x7ff && code <= 0xffff) {
      s += 2;
    }
  }
  return s;
}

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray(actual) {
  const newArray = [];
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

/**
 * @param {Object} json
 * @returns {Array}
 */
export function param(json) {
  if (!json) {
    return "";
  }
  return cleanArray(
    Object.keys(json).map((key) => {
      if (json[key] === undefined) {
        return "";
      }
      return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]);
    })
  ).join("&");
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = url.split("?")[1];
  if (!search) {
    return {};
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"')
        .replace(/\+/g, " ") +
      '"}'
  );
}

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text(val) {
  const div = document.createElement("div");
  div.innerHTML = val;
  return div.textContent || div.innerText;
}

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge(target, source) {
  if (typeof target !== "object") {
    target = {};
  }
  if (Array.isArray(source)) {
    return source.slice();
  }
  Object.keys(source).forEach((property) => {
    const sourceProperty = source[property];
    if (typeof sourceProperty === "object") {
      target[property] = objectMerge(target[property], sourceProperty);
    } else {
      target[property] = sourceProperty;
    }
  });
  return target;
}

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass(element, className) {
  if (!element || !className) {
    return;
  }
  let classString = element.className;
  const nameIndex = classString.indexOf(className);
  if (nameIndex === -1) {
    classString += "" + className;
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length);
  }
  element.className = classString;
}

/**
 * @param {string} type
 * @returns {Date}
 */
export function getTime(type) {
  if (type === "start") {
    return new Date().getTime() - 3600 * 1000 * 24 * 90;
  } else {
    return new Date(new Date().toDateString());
  }
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result;

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp;

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) {
          context = args = null;
        }
      }
    }
  };

  return function (...args) {
    context = this;
    timestamp = +new Date();
    const callNow = immediate && !timeout;
    // 如果延时不存在，重新设定延时
    if (!timeout) {
      timeout = setTimeout(later, wait);
    }
    if (callNow) {
      result = func.apply(context, args);
      context = args = null;
    }

    return result;
  };
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
  if (!source && typeof source !== "object") {
    throw new Error("error arguments", "deepClone");
  }
  const targetObj = source.constructor === Array ? [] : {};
  Object.keys(source).forEach((keys) => {
    if (source[keys] && typeof source[keys] === "object") {
      targetObj[keys] = deepClone(source[keys]);
    } else {
      targetObj[keys] = source[keys];
    }
  });
  return targetObj;
}

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr(arr) {
  return Array.from(new Set(arr));
}

/**
 * @returns {string}
 */
export function createUniqueString() {
  const timestamp = +new Date() + "";
  const randomNum = parseInt((1 + Math.getRandomValues()) * 65536) + "";
  return (+(randomNum + timestamp)).toString(32);
}

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele, cls) {
  return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
}

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass(ele, cls) {
  if (!hasClass(ele, cls)) {
    ele.className += " " + cls;
  }
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
    ele.className = ele.className.replace(reg, " ");
  }
}

export function buildTimeSelectOptions(start, end, step) {
  const parseTimeTwo = function (time) {
    const values = (time || "").split(":");
    if (values.length >= 2) {
      const hours = parseInt(values[0], 10);
      const minutes = parseInt(values[1], 10);

      return {
        hours,
        minutes,
      };
    }
    /* istanbul ignore next */
    return null;
  };
  const compareTime = function (time1, time2) {
    const value1 = parseTimeTwo(time1);
    const value2 = parseTimeTwo(time2);

    const minutes1 = value1.minutes + value1.hours * 60;
    const minutes2 = value2.minutes + value2.hours * 60;

    if (minutes1 === minutes2) {
      return 0;
    }

    return minutes1 > minutes2 ? 1 : -1;
  };
  const formatTime = function (time) {
    return (
      (time.hours < 10 ? "0" + time.hours : time.hours) +
      ":" +
      (time.minutes < 10 ? "0" + time.minutes : time.minutes)
    );
  };
  const nextTime = function (time, stepTwo) {
    const timeValue = parseTimeTwo(time);
    const stepValue = parseTimeTwo(stepTwo);

    const next = {
      hours: timeValue.hours,
      minutes: timeValue.minutes,
    };

    next.minutes += stepValue.minutes;
    next.hours += stepValue.hours;

    next.hours += Math.floor(next.minutes / 60);
    next.minutes = next.minutes % 60;

    return formatTime(next);
  };
  const result = [];
  let current = start;
  while (compareTime(current, end) <= 0) {
    result.push({
      value: current,
      disabled:
        compareTime(current, this.minTime || "-1:-1") <= 0 ||
        compareTime(current, this.maxTime || "100:100") >= 0,
    });
    current = nextTime(current, step);
  }
  return result;
}

// 封装简写的vue请求
export class $v {
  static getHost() {
    let host = location.host;
    if (host === "127.0.0.1:8200" || host === "localhost:8200") {
      host = "119.3.231.17:38200";
    }
    return host;
  }
  /*
   * vue: 当前是以this.vue.$http或者this.vue.http方式请求(Vue、this)
   * url:请求链接
   * data:请求参数
   * success:请求成功回调
   * error:请求失败时是否报错(true时不报错),error三种形式:1.为function时调用 2.为true时不弹出提示错误，而是控制台输出  3.为false时弹出提示错误
   * loadParam对象: 属性loading,是否有加载动画,check是否校验,
   */
  static get(vue, url, params, success, error, loadParam = {}) {
    loadParam.connectMode = "get";
    this.beforeConnect(vue, url, params, success, error, loadParam);
  }
  static post(vue, url, params, success, error, loadParam = {}) {
    loadParam.connectMode = "post";
    this.beforeConnect(vue, url, params, success, error, loadParam);
  }
  static upload(vue, url, params, success, error, loadParam = {}) {
    loadParam.connectMode = "post";
    const $loginInfo = $store.get("$loginInfo");
    params = params || {};
    if (this.haveLoginInfo($loginInfo)) {
      // 存在登录数据
      params.creator = $loginInfo.userAccount;
      if (!params.tenantId && !this.isEmpty($loginInfo.tenantId)) {
        // 非空
        params.tenantId = $loginInfo.tenantId;
      }
    }
    loadParam.isLocation = true;
    url = baserServerUrl + "/" + url;
    this.connect(vue, url, params, success, error, loadParam);
  }
  static postNoLoadCheck(vue, url, params, success, error) {
    const loadParam = {
      loading: false,
      check: false,
    };
    this.post(
      vue,
      url,
      params,
      (resp) => {
        if (success) {
          const isArray = isArrayFn(resp.data);
          if ((isArray && resp.data.length > 0) || !isArray) {
            success(resp);
          }
        }
      },
      error,
      loadParam
    );
    function isArrayFn(value) {
      if (typeof Array.isArray === "function") {
        return Array.isArray(value);
      } else {
        return Object.prototype.toString.call(value) === "[object Array]";
      }
    }
  }
  static postNoCheck(vue, url, params, success, error) {
    const loadParam = {
      loading: false,
      check: false,
    };
    params.__ctCbAllCode = true; // 主程序只拦截401
    this.post(
      vue,
      url,
      params,
      (resp) => {
        if (success) {
          success(resp);
        }
      },
      error,
      loadParam
    );
  }
  static countTimeout(vue, check) {
    const loginFlag = Number($cookie.get("loginFlag"));
    const time = new Date().getTime();
    if (
      !loginFlag ||
      time - loginFlag < 0 ||
      time - loginFlag > 60000 * 60 * 24
    ) {
      if (!check) {
        this.jumpHome(vue);
      }
      return false;
    } else {
      if (!check) {
        $cookie.set("loginFlag", time);
      }
    }
    return true;
  }
  static validateLogin(vue, check) {
    // 校验是否登录
    if (vue.$route.path.indexOf("login") !== -1) {
      return true;
    }
    const loginInfo = $store.get("$loginInfo");
    if (loginInfo && loginInfo.userId) {
      if (!this.countTimeout(vue, check)) {
        return false;
      }
      const authorities = loginInfo.authorities;
      if (authorities && authorities.length > 0) {
        return true;
      } else {
        this.message({
          mess: "用户无角色",
        });
        return false;
      }
    } else {
      this.jumpHome(vue);
      return false;
    }
  }
  static outLoginCount = 0;
  static connectCount = 0;
  static beforeConnect(vue, url, params, success, error, loadParam) {
    const check = loadParam.check;
    const $loginInfo = $store.get("$loginInfo");
    // if(!this.validateLogin(vue, check)){//未登录
    //   return false;
    // }
    params = params || {};
    if (this.haveLoginInfo($loginInfo)) {
      // 存在登录数据
      params.creator = $loginInfo.userAccount;
      if (!params.tenantId && !this.isEmpty($loginInfo.tenantId)) {
        // 非空
        params.tenantId = $loginInfo.tenantId;
      }
    }

    const host = location.host;
    let isLocation = false;
    if (host === "localhost:9998") {
      isLocation = true;
    }
    loadParam.isLocation = isLocation;
    this.connect(vue, url, params, success, error, loadParam);
  }

  static connect(vue, url, params, success, error, loadParam) {
    const connectMode = loadParam.connectMode;
    const loading = loadParam.loading;
    const onUploadProgress = loadParam.onUploadProgress;

    const _this = this;
    let loadingInstance;
    if (loading !== false) {
      _this.connectCount++;
      loadingInstance = Loading.service({ fullscreen: true });
    }

    // 获取请求axios的实例
    if (connectMode === "post") {
      if (url.indexOf("?") > -1) {
        url += "&";
      } else {
        url += "?";
      }
      url += new Date().getTime();
      if (loadParam.isLocation) {
        request({
          method: "post",
          url,
          data: params,
          onUploadProgress,
        }).then(
          (d) => {
            // 关闭加载动画
            _this.closeLoading(loading, loadingInstance);
            _this.judgmentReturn(vue, d, success); // 判断返回数据
          },
          (d) => {
            // 关闭加载动画
            _this.closeLoading(loading, loadingInstance);
            _this.judgmentReturnError(vue, d, error);
          }
        );
      } else {
        this.requestSDK(vue, url, params, "post").then(
          function (d) {
            // 关闭加载动画
            _this.closeLoading(loading, loadingInstance);
            console.log("d.code : ", d.code);
            if (
              d.code === 200 ||
              d.code === 4000 ||
              String(d.code).substring(0, 3) === "300"
            ) {
              // 解决sdk400已返回到成功中的问题
              _this.judgmentReturn(vue, d, success); // 判断返回数据
            } else {
              _this.judgmentReturnError(vue, d, error);
            }
          },
          (d) => {
            // 关闭加载动画
            _this.closeLoading(loading, loadingInstance);
            _this.judgmentReturnError(vue, d, error);
          }
        );
      }
    } else {
      if (loadParam.isLocation) {
        let p = "";
        if (params) {
          Object.keys(params).forEach(function (i) {
            p += i + "=" + params[i] + "&";
          });
          p = p.replace(/&$/, ""); // 请求类型为管理端(用户端不传)
        }
        if (p) {
          url += "?" + p;
        }
        request.get(url).then(
          function (d) {
            // 关闭加载动画
            _this.closeLoading(loading, loadingInstance);
            _this.judgmentReturn(vue, d, success); // 判断返回数据
          },
          (d) => {
            // 关闭加载动画
            _this.closeLoading(loading, loadingInstance);
            _this.judgmentReturnError(vue, d, error);
          }
        );
      } else {
        this.requestSDK(vue, url, params, "get").then(
          function (d) {
            // 关闭加载动画
            _this.closeLoading(loading, loadingInstance);
            if (
              d.code === 200 ||
              d.code === 4000 ||
              String(d.code).substring(0, 3) === "300"
            ) {
              // 解决sdk400已返回到成功中的问题
              _this.judgmentReturn(vue, d, success); // 判断返回数据
            } else {
              _this.judgmentReturnError(vue, d, error);
            }
          },
          (d) => {
            // 关闭加载动画
            _this.closeLoading(loading, loadingInstance);
            _this.judgmentReturnError(vue, d, error);
          }
        );
      }
    }
  }
  static async requestSDK(vue, url, params, method) {
    if (params.responseType) {
      const responseType = params.responseType;
      delete params.responseType;
      return await requestSDK(url, params, {}, method, responseType);
    }
    return await requestSDK(url, params, {}, method);
  }

  /**
   * 关闭加载动画
   * @param loading
   * @param loadingInstance
   */
  static closeLoading(loading, loadingInstance) {
    if (loading !== false) {
      this.connectCount--;
      if (this.connectCount <= 0) {
        this.connectCount = 0;
        loadingInstance.close();
      }
    }
  }
  /**
   * {type} success: 成功, warning: 提示, error: 警告; 不区分大小写
   * {mess, message} 消息内容; 必选其一
   * {data} 消息详情; 可选
   */
  static message(param = {}) {
    if (typeof param === "string") {
      const mess = param;
      param = {
        type: "success",
        mess: mess,
      };
    }
    param.type = param.type.toLowerCase();
    const duration = 5000;
    const only = new Date().getTime();
    const ob = {
      type: param.type,
      message: param.mess || param.message || "null",
      duration: duration,
      showClose: true,
      customClass: "message-new message-" + param.type + "-new" + " " + only,
    };
    if (param.data) {
      ob.customClass += " message-more-new";
      ob.dangerouslyUseHTMLString = true;
      ob.message +=
        '<span class="more-til" onclick="lookMessageDetail(' +
        only +
        ')">显示详情</span>';
      ob.message += '<div class="more-detail">';
      if (typeof param.data === "string") {
        ob.message += param.data;
      } else {
        ob.message += '<div class="more-left">' + param.data[0] + "</div>";
        ob.message += '<div class="more-right">' + param.data[1] + "</div>";
      }
      ob.message += "</div>";
    }
    setTimeout(() => {
      iframeSDK({
        iframeOperationId: "message",
        ...ob,
      });
    });
  }
  static outLogin(vue, mess) {
    this.jumpHome(vue, mess);
  }
  static jumpHome(vue, mess) {
    // 返回首页
    if (vue.$route.path.indexOf("login") !== -1) {
      return false;
    }
    $session.clear();
    $store.clear();
    $cookie.clear();
    if (mess) {
      MessageBox.alert(mess, "", {
        confirmButtonText: "确定",
        center: true,
        callback: (action) => {
          this.jumpMenu(vue, "/");
        },
      });
    } else {
      this.jumpMenu(vue, "/");
    }
    this.socketClose();
  }
  static socketClose() {
    if (window.socket1) {
      window.socket1.close();
    }
    if (window.socket2) {
      window.socket2.close();
    }
    if (window.mesList) {
      for (const key in window.mesList) {
        window.mesList[key].close();
      }
    }
  }
  static jumpMenu(vue, e, _blank) {
    // 跳转链接
    let href = window.location.href;
    href = href.substring(href.indexOf("#") + 1, href.length);
    let url;
    if (typeof e === "object") {
      url = e.url;
      _blank = e.blank || _blank;
    } else {
      url = e;
    }
    if (url && href != url) {
      if (!_blank) {
        vue.$router.push({
          path: url,
        });
      } else {
        _blank = vue.$router.resolve(url);
        window.open(_blank.href, "_blank");
      }
    }
  }
  static judgmentReturn(vue, d, success) {
    // 判断返回数据
    if (success) {
      let dStr = JSON.stringify(d);
      if (
        location.hostname === "localhost" ||
        location.hostname === "127.0.0.1"
      ) {
        dStr = dStr.replace(
          /https:\/\/powerexchange-fs.obs.cn-north-4.myhuaweicloud.com:443/g,
          location.origin + urlImg
        );
      }
      if (location.protocol === "https:") {
        dStr = dStr.replace(
          /http:\/\/124.70.52.86:10120/g,
          location.origin + "/port10120"
        ); // 准生产

        dStr = dStr.replace(
          /http:\/\/124.71.226.241:10120/g,
          location.origin + "/zport10120_1"
        );
        dStr = dStr.replace(
          /http:\/\/58.215.54.4:10120/g,
          location.origin + "/zport10120_2"
        );
        dStr = dStr.replace(
          /http:\/\/36.150.52.5:10120/g,
          location.origin + "/zport10120_3"
        );
        dStr = dStr.replace(
          /http:\/\/114.66.236.4:10120/g,
          location.origin + "/zport10120_4"
        );
        dStr = dStr.replace(
          /http:\/\/223.85.23.83:10120/g,
          location.origin + "/zport10120_5"
        );
        dStr = dStr.replace(
          /http:\/\/182.151.249.22:10120/g,
          location.origin + "/zport10120_6"
        );
        dStr = dStr.replace(
          /http:\/\/101.206.244.211:10120/g,
          location.origin + "/zport10120_7"
        );
        dStr = dStr.replace(
          /http:\/\/122.9.214.147:10120/g,
          location.origin + "/zport10120_8"
        );
        dStr = dStr.replace(
          /http:\/\/122.9.215.1:10120/g,
          location.origin + "/zport10120_9"
        );
        dStr = dStr.replace(
          /http:\/\/122.9.210.68:10120/g,
          location.origin + "/zport10120_10"
        );
        dStr = dStr.replace(
          /http:\/\/114.116.214:10120/g,
          location.origin + "/zport10120_11"
        );
        dStr = dStr.replace(
          /http:\/\/122.9.11.27:10120/g,
          location.origin + "/zport10120_12"
        );
        dStr = dStr.replace(
          /http:\/\/36.138.41.32:10120/g,
          location.origin + "/zport10120_13"
        );
        dStr = dStr.replace(
          /http:\/\/111.29.61.135:10120/g,
          location.origin + "/zport10120_14"
        );
      }
      d = JSON.parse(dStr);
      success(d);
    }
  }

  static judgmentReturnError(vue, d, error) {
    // 判断返回异常的数据
    if (d.status === 401 || d.status === 410) {
      if (this.outLoginCount === 0) {
        this.jumpHome(vue);
      }
      this.outLoginCount++;
      return false;
    } else {
      this.outLoginCount = 0;
    }
    if (error) {
      d.resultStat = "ERROR";
      d.mess = "系统繁忙，请稍后再试";
      error(d);
    }
  }

  // 判断字符是否为空
  static isEmpty(str) {
    return (
      typeof str === "undefined" || str === null || str === "" || str === " "
    );
  }
  // 判断字符是否为空
  static haveLoginInfo($loginInfo) {
    return (
      $store.get("$loginInfo") &&
      JSON.stringify($loginInfo) !== "{}" &&
      $store.get("$loginInfo")
    );
  }

  /**
   * 查询枚举值
   */
  static doEnumInfoQry(vue, enumTypeId, success) {
    /* 获取枚举值 */
    const url = urlSystem + "/system/getEnumInfo";
    this.post(
      vue,
      url,
      { enumTypeId: enumTypeId },
      (resp) => {
        if (
          resp &&
          resp["resultStat"] === "SUCCESS" &&
          resp.data.list.length > 0
        ) {
          if (success) {
            success(resp);
          }
        }
      },
      null,
      false
    );
  }
  static openPage(url, params) {
    params.timer = new Date().getTime();
    postMsgUtil.trigger(null, "redirectTo", {
      isOpener: true, //  isOpener 是否打开新页面，true：是，false：否
      url: url, // 要跳转的工作台URL地址
      params: params,
    });
  }

  static openPageBig(url, params) {
    params.timer = new Date().getTime();
    postMsgUtil.trigger(null, "redirectTo", {
      isOpener: true, //  isOpener 是否打开新页面，true：是，false：否
      url: url, // 要跳转的工作台URL地址
    });
  }
}

/**
 * 8.3.	获取当前用户信息
 */
export async function getInfo() {
  return await requestSDK("getInfo");
}

/**
 * 8.4.	权限获取
 */
export async function getPermissionsByTarget() {
  return await requestSDK("getPermissionsByTarget");
}

/**
 * 计算两个时间之间的小时数
 * @param {*} date1
 * @param {*} date2
 */
export function getHoursByTwoDate(date1, date2) {
  const dateOne = new Date(date1);
  const dateTwo = new Date(date2);
  const ms = dateTwo.getTime() - dateOne.getTime();
  if (ms < 0) {
    return 0;
  }
  return (ms / 1000 / 60 / 60).toFixed(2);
}
const TokenKey = "Admin-Token";
export function getToken() {
  return sessionStorage.getItem(TokenKey);
}

export function setToken(token) {
  return sessionStorage.setItem(TokenKey, token);
}

/**
 * level 0为全国,1为省,2为地市,3为区县
 * code 行政区划编码 全国取首都,省取省会
 * @param success 成功回调
 */
export function getOrderAuthority(success) {
  const url = urlBaseService + "/area/getDataScopeObj";
  const loadParam = {
    loading: false,
    check: false,
  };
  $v.post(
    this,
    url,
    {},
    (resp) => {
      let code;
      let level;
      const areaList = resp.data.areaList;
      if (areaList && areaList.length > 0) {
        if (
          areaList.every(
            (item) => item.provinceCode === areaList[0].provinceCode
          )
        ) {
          // 省全等
          if (
            areaList.every((item) => item.cityCode === areaList[0].cityCode)
          ) {
            // 地市全等
            if (
              areaList.every(
                (item) => item.countyCode === areaList[0].countyCode
              )
            ) {
              // 区县全等
              code = areaList[0].countyCode;
              level = 3;
            } else {
              // 有不等的区县取地市
              code = areaList[0].cityCode;
              level = 2;
            }
          } else {
            // 有不等的地市取省
            code = areaList[0].provinceCode;
            level = 1;
          }
        } else {
          // 多个省全国
          code = "100000";
          level = 0;
        }
      } else {
        // 多个省全国
        code = "100000";
        level = 0;
      }
      if (success) {
        success(code, level);
      }
    },
    null,
    loadParam
  );
}

/**
 * code 行政区划编码
 * @param success 成功回调
 */
export function getTenantArea(success) {
  let areaCode = "";
  let areaType = "";
  let adCode = "";
  getUserMemoryInfo(["chooseArea"], (resp) => {
    for (const item of resp.data) {
      if (item.memoryType === "chooseArea" && item.memoryValue) {
        const areaArrays = item.memoryValue.split("`");
        adCode = areaArrays[0];
        areaCode = areaArrays[1];
        areaType = Number(areaArrays[2]);
      }
    }
    if (areaCode == null || areaCode === "") {
      // 查询用户订购权限
      getOrderAuthority((code, level) => {
        if (level === 1) {
          // 省级
          getSysCapital(code, (adCode2) => {
            if (success) {
              success({
                adCode: adCode2,
                areaCode: code,
                areaType: level,
              });
            }
          });
        } else {
          if (success) {
            success({
              adCode: code,
              areaCode: code,
              areaType: level,
            });
          }
        }
      });
    } else {
      if (success) {
        success({
          adCode: adCode,
          areaCode: areaCode,
          areaType: areaType,
        });
      }
    }
  });
}

/**
 * 查询省份的省会
 */
export function getSysCapital(provCode, success) {
  const url = urlBaseService + "/area/getSysCapital";
  const params = {
    provCode: provCode,
  };
  $v.postNoCheck(this, url, params, (resp) => {
    let adCode;
    if (resp && resp.data) {
      adCode = resp.data.capitalCode;
    } else {
      adCode = provCode;
    }
    if (success) {
      success(adCode);
    }
  });
}

// 获取 url originKey
export function getQueryString(name) {
  const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  const r = window.location.search.substr(1).match(reg);
  if (r != null) {
    return decodeURIComponent(r[2]);
  }
  return null;
}

/**
 * 跳转新tag页面(自行操作)
 */
export function redirectToPage(name, redirectUrl, params = {}) {
  postMsgUtil.trigger(null, "redirectTo", {
    url: redirectUrl, // 要打开的页面地址
    params: {
      originKey: getQueryString("originKey"), // 来源的唯一标识，必须
      ...params,
      metaTitle: name, // 自定义tag标签标题
    },
  });
}

/**
 * 返回（关闭）来源tag页面(自行操作)
 */
export function backToPage(redirectUrl, params = {}) {
  postMsgUtil.trigger(null, "backToOrigin", {
    isClose: true, // 是否关闭当前tag页面，true 为关闭、flase 为不关闭
    data: {
      originKey: getQueryString("originKey"), // 来源的唯一标识，必须
      ...params,
    },
  });
}

/* 获取url地址 */
export const $getUrlParam = (name, webUrl) => {
  try {
    if (webUrl == null) {
      webUrl = window.location.href;
    }

    if (webUrl.indexOf("?") === -1) {
      return "";
    }
    const params = webUrl.split("?")[1];
    const strs = params.split("&");
    const param = {};
    for (let i = 0; i < strs.length; i++) {
      param[strs[i].split("=")[0]] = strs[i].split("=")[1];
    }
    const resp = param[name] || "";
    return decodeURI(resp);
  } catch (e) {
    return "";
  }
};
export function getUrlHead() {
  let url = "";
  // if (parent !== window) {
  //  try {
  //    url = parent.location.href;
  //  }catch (e) {
  //  	if(document.referrer){
  //  		url = new URL(document.referrer).protocol + '//' + new URL(document.referrer).host + '/';
  //  	}
  //  }
  // }
  if (document.referrer) {
    url =
      new URL(document.referrer).protocol +
      "//" +
      new URL(document.referrer).host +
      "/";
  }
  const pathname = window.document.location.pathname;
  const pos = url.indexOf(pathname);
  if (pos > -1) {
    // 兼容弹窗搜索不到的
    return url.substring(0, pos);
  } else {
    if (url.substring(url.length - 1, url.length) === "/") {
      return url.substring(0, url.length - 1);
    }
    return url;
  }
}

Date.prototype.Format = function (fmt) {
  function getYearWeek(date) {
    var date1 = new Date(date.getFullYear(), date.getMonth(), date.getDate());
    var date2 = new Date(date.getFullYear(), 0, 1);

    // 获取1月1号星期（以周一为第一天，0周一~6周日）
    var dateWeekNum = date2.getDay() - 1;
    if (dateWeekNum < 0) {
      dateWeekNum = 6;
    }
    if (dateWeekNum < 4) {
      // 前移日期
      date2.setDate(date2.getDate() - dateWeekNum);
    } else {
      // 后移日期
      date2.setDate(date2.getDate() + 7 - dateWeekNum);
    }
    var d = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
    if (d < 0) {
      var date3 = new Date(date1.getFullYear() - 1, 11, 31);
      return getYearWeek(date3);
    } else {
      // 得到年数周数
      var year = date1.getFullYear();
      var week = Math.ceil((d + 1) / 7);
      return week;
    }
  }

  var o = {
    "M+": this.getMonth() + 1, // 月份
    "d+": this.getDate(), // 日
    "h+": this.getHours(), // 小时
    "m+": this.getMinutes(), // 分
    "s+": this.getSeconds(), // 秒
    "q+": Math.floor((this.getMonth() + 3) / 3), // 季度
    S: this.getMilliseconds(), // 毫秒
    "W+": getYearWeek(this), // 周数
  };
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (this.getFullYear() + "").substr(4 - RegExp.$1.length)
    );
  }

  for (var k in o) {
    if (new RegExp("(" + k + ")").test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
      );
    }
  }

  return fmt;
};

export function getDataString(date) {
  var year = date.getFullYear().toString().padStart(4, "0");
  var month = (date.getMonth() + 1).toString().padStart(2, "0");
  var day = date.getDate().toString().padStart(2, "0");
  return `${year}-${month}-${day}`;
}

/**
 * 注册消息推送事件监听（建议放全局）
 */
export function registerSocket() {
  postMsgUtil.trigger(null, "registerNoticePush", {
    industryCode: "100000", // 新林业行业编码
  });
}

/**
 * 关闭消息推送事件监听（建议放全局）
 */
export function closeSocket() {
  postMsgUtil.trigger(null, "unRegisterNoticePush", {
    industryCode: "100000", // 新林业行业编码
  });
}

/**
 * 监听消息推送事件
 */
export function listenSocket(success) {
  postMsgUtil.listen("noticePushListen", function (data) {
    // 对应数据格式见下图
    if (success) {
      success(data);
    }
  });
}

/**
 * 监听切换Tab回调
 */
export function listenTab(success) {
  postMsgUtil.listen("noticeRedirectToCB", function (data) {
    // 对应数据格式见下图
    if (success) {
      success(data);
    }
  });
}

/**
 * 获取监听消息信息
 */
export function ejectMsg() {
  console.log("%c成功进入监听消息", "color: #FAC800");
  listenSocket((resp) => {
    console.log("%c这是行业监听到的消息推送: ", "color: #FAC800", resp);
    if (resp) {
      if (resp.showType !== "2") {
        // 0全部 1大屏 2工作台
        if (resp.notifyType === "5") {
          // 1事件消息 5森林火险预警消息
          const str = resp.industryExtend;
          resp.titleInfo = eval("(" + str + ")");
          if (resp.industryFlag != null && resp.industryFlag !== "") {
            if (refreshWarn && typeof refreshWarn === "function") {
              refreshWarn();
            }
          }
        }
        const msgHtml = getMessageHtml(resp);
        setTimeout(() => {
          Notification(
            {
              customClass: "bigScreenMsgClass",
              title: "",
              dangerouslyUseHTMLString: true,
              message: msgHtml,
              // duration: 0,
              offset: -16,
            },
            200
          );
        });
        if (resp.alarmFlag === "1") {
          // 播放声音
          const param = {
            msgId: resp.msgId,
            alarmFlag: "1",
          };
          window.parent.postMessage(param, "*");
          // 1S后关闭声音
          setTimeout(() => {
            const param = {
              msgId: resp.msgId,
              alarmFlag: "0",
            };
            window.parent.postMessage(param, "*");
          }, 1000);
        }
      }
    }
  });
}

/**
 * 告警消息跳转
 */
export function goOrderInfo(msgId, orderStatus) {
  console.log("%c跳转参数：", "color: #FAC800", msgId);
  // 判断是否有融合通信权限
  // let pageRouter = '/bigScreen/monitorWarn';//原大屏监测预警地址
  let pageRouter = "";
  const callStatus = $store.get("winCallStatus"); // 获取本次登录用户是否有权限
  if (callStatus) {
    pageRouter = "/bigScreen/monitorWarnOnCall";
  } else {
    pageRouter = "/bigScreen/monitorWarnOffCall";
  }
  // 大屏消息tab切换
  postMsgUtil.trigger(null, "noticeRedirectTo", {
    industryCode: "100000", // 新行业版本（必填）
    pageRouter: pageRouter, // 要切换的页面地址（必填）
    msgId: msgId, // 消息通知ID（必填）
  });
}

export function listenMsgTab() {
  console.log("%c这是listenTab监听已开启", "color: #FAC800");
  listenTab((resp) => {
    console.log("%c这是listenTab返回：", "color: #FAC800", resp);
    if (resp) {
      const params = {};
      params.orderId = resp.msgId;
      fromMsgGetEvent(params);
    }
  });
}

export function listenNode(node, type, callback) {
  node.addEventListener(type, callback);
  return {
    destroy() {
      node.removeEventListener(type, callback);
    },
  };
}

export function dragBind(el) {
  const odiv = el; // 获取当前元素
  el.onmousedown = (e) => {
    e.stopPropagation();
    if (el._prevClass.indexOf("stop-drag") === -1) {
      // 算出鼠标相对元素的位置
      const disX = e.clientX - odiv.offsetLeft;
      const disY = e.clientY - odiv.offsetTop;
      let left = "";
      let top = "";
      document.onmousemove = (e) => {
        // 用鼠标的位置减去鼠标相对元素的位置，得到元素的位置
        left = e.clientX - disX;
        top = e.clientY - disY;
        // 绑定元素位置到positionX和positionY上面
        // 移动当前元素
        odiv.style.left = left + "px";
        odiv.style.top = top + "px";
      };
      document.onmouseup = () => {
        document.onmousemove = null;
        document.onmouseup = null;
      };
    }
  };
  el.addEventListener("touchstart", (e) => {
    console.log("------------------触摸屏点击");
    e.stopPropagation();
    if (el._prevClass.indexOf("stop-drag") === -1) {
      const touch1 = e.touches[0];
      // 算出鼠标相对元素的位置
      const disX = touch1.clientX - odiv.offsetLeft;
      const disY = touch1.clientY - odiv.offsetTop;
      let left = "";
      let top = "";
      const destroyMove = listenNode(document, "touchmove", (e) => {
        console.log("-----------触摸屏移动");
        const touch2 = e.touches[0];
        // 用鼠标的位置减去鼠标相对元素的位置，得到元素的位置
        left = touch2.clientX - disX;
        top = touch2.clientY - disY;
        // 绑定元素位置到positionX和positionY上面
        // 移动当前元素
        odiv.style.left = left + "px";
        odiv.style.top = top + "px";
      });

      const destroyEnd = listenNode(document, "touchend", (e) => {
        console.log("-----------触摸屏停止");
        destroyMove.destroy();
        destroyEnd.destroy();
      });
    }
  });
}

// 防抖函数
export function _debounce(fn, delay) {
  var delay = delay || 200;
  var timer;
  return function () {
    var th = this;
    var args = arguments;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(function () {
      timer = null;
      fn.apply(th, args);
    }, delay);
  };
}

export function randomFloat() {
  const crypto = window.crypto || window.msCrypto;
  const array = new Uint32Array(1);
  return crypto.getRandomValues(array)[0];
}

/**
 * 获取天气图标
 */
export function getWeatherIcon(weatherText) {
  let icon;
  if (weatherText) {
    if (weatherText.substring(weatherText.length - 1) === "天") {
      weatherText = weatherText.substring(0, weatherText.length - 1);
    }
    const weatherIcon = {
      晴: "icon-qing1",
      夜间晴: "icon-yejianqingtian",
      阴: "icon-yintian",
      多云: "icon-duoyun",
      夜间多云: "icon-yejianduoyun",
      阵雨: "icon-zhenyu",
      小雨: "icon-xiaoyu",
      中雨: "icon-zhongyu",
      大雨: "icon-dayu",
      暴雨: "icon-baoyu",
      雷阵雨: "icon-leizhenyu",
      阵雪: "icon-zhenxue",
      小雪: "icon-xiaoxue",
      中雪: "icon-zhongxue",
      大雪: "icon-daxue",
      暴雪: "icon-baoxue",
      雾: "icon-wu",
      夜间雾: "icon-yejianwu",
      浮尘: "icon-fuchen",
      扬沙: "icon-yangsha",
      沙尘暴: "icon-shachenbao",
      大暴雨: "icon-dabaoyu1",
      特大暴雨: "icon-tedabaoyu1",
      冻雨: "icon-dongyu1",
      大雨转暴雨: "icon-dayuzhuanbaoyu1",
      龙卷风: "icon-longjuanfeng",
      雾霾: "icon-yinmai",
      带冰雹雷阵雨: "icon-daibingbaoleizhenyu",
      小雨转中雨: "icon-xiaoyuzhuanzhongyu1",
      中雨转大雨: "icon-zhongyuzhuandayu1",
      雨夹雪: "icon-yujiaxue1",
      小雪转中雪: "icon-xiaoxuezhuanzhongxue1",
      中雪转大雪: "icon-zhongxuezhuandaxue1",
      台风: (icon = "icon-taifeng"),
    };
    icon = weatherIcon[weatherText];
    if (!icon) {
      icon = "icon-wushuju"; // 无数据
    }
  } else {
    icon = "icon-wushuju"; // 无数据
  }
  return icon;
}

/**
 * @description iframe弹出框
 * @param type 操作类型, add: 新建弹窗, del: 删除弹窗, move: 移动弹窗, get: 获取iframe信息
 * @param params
 * @param iframeDialogMoving
 * @param params.key 唯一标识, 弹窗生成的id: iframeRef+params.key
 * @param params.src iframe完整地址, 新增弹窗时必传
 * @param params.iframeIds 获取iframe信息的key数组
 * @param params.width 弹框的width
 * @param params.height 弹框的height
 * @param params.left 弹框的left
 * @param params.top 弹框的left
 * @param params.right 弹框的left
 * @param params.bottom 弹框的left
 * @param params.move 拖拽位移参数
 * @param params.zIndex 弹框层级
 */
let iframeDialogMoving = false;
export async function iframeDialog(type, params) {
  const keyBefore = "iframeRef";
  const viewId = $getUrlParam("viewId");
  params = params || {};
  const iframeIds = [];
  if (params.key) {
    let key = keyBefore + params.key;
    if (type === "move") {
      key += viewId;
    }
    iframeIds.push(key);
  }
  params.iframeIds = params.iframeIds || [];
  params.iframeIds.forEach((key) => {
    iframeIds.push(keyBefore + key + viewId);
  });
  const windowInfo = await requestSDK("getWindowInfo", {
    iframeIds: iframeIds,
    only: new Date().getTime() + "" + randomFloat(),
  });
  const iframeInfo = windowInfo.data.iframeInfo || {};
  if (iframeInfo[keyBefore + params.key]) {
    iframeInfo[params.key] = iframeInfo[keyBefore + params.key];
  }
  params.iframeIds.forEach((key) => {
    if (iframeInfo[keyBefore + key + viewId]) {
      iframeInfo[key] = iframeInfo[keyBefore + key + viewId];
    }
  });
  if (type === "get") {
    return new Promise((resolve) => {
      resolve(windowInfo.data);
    });
  }
  const cw = windowInfo.data.width; // 容器宽
  const ch = windowInfo.data.height; // 容器高
  let percentW, percentH, percentX, percentY;
  let fitW = 0;
  if (type === "add") {
    fitW = 1;
  }
  if (params.width) {
    const vw = params.width + fitW; // 弹框元素宽, 加1是为了计算百分比时缺边
    percentW = (vw / cw) * 100 + "%"; // 弹框相对于容器宽度百分比
    if (type === "add") {
      const vx = (cw - vw) / 2; // 弹框left
      percentX = (vx / cw) * 100 + "%"; // 弹框相对于容器left百分比
    }
  }
  if (params.height) {
    const vh = params.height + fitW; // 弹框元素高, 加1是为了计算百分比时缺边
    percentH = (vh / ch) * 100 + "%"; // 弹框相对于容器高度百分比
    if (type === "add") {
      const vy = (ch - vh) / 2; // 弹框top
      percentY = (vy / ch) * 100 + "%"; // 弹框相对于容器top百分比
    }
  }
  if (params.left != null) {
    percentX = (params.left / cw) * 100 + "%"; // 弹框相对于容器left百分比
  }
  if (params.top != null) {
    percentY = (params.top / ch) * 100 + "%"; // 弹框相对于容器top百分比
  }
  let vIframe;
  if (type === "move") {
    vIframe = iframeInfo[keyBefore + params.key + viewId];
  } else {
    vIframe = iframeInfo[keyBefore + params.key];
  }
  if (params.right != null && (params.width || vIframe)) {
    percentX =
      ((cw - (params.width || vIframe.offsetWidth) - params.right) / cw) * 100 +
      "%"; // 弹框相对于容器left百分比
  }
  if (params.bottom != null && (params.height || vIframe)) {
    percentY =
      ((ch - (params.height || vIframe.offsetHeight) - params.bottom) / ch) *
        100 +
      "%"; // 弹框相对于容器top百分比
  }
  if (params.move && vIframe) {
    if (iframeDialogMoving && params.fixed == null) {
      return false;
    }
    iframeDialogMoving = true;
    setTimeout(() => {
      iframeDialogMoving = false;
    }, 80);
    if (params.move.left) {
      let x = vIframe.offsetLeft + params.move.left;
      x = x < 0 ? 0 : x;
      x = x > cw - vIframe.offsetWidth ? cw - vIframe.offsetWidth : x;
      percentX = (x / cw) * 100 + "%";
    }

    if (params.move.top) {
      let y = vIframe.offsetTop + params.move.top;
      y = y < 0 ? 0 : y;
      y = y > ch - vIframe.offsetHeight ? ch - vIframe.offsetHeight : y;
      percentY = (y / ch) * 100 + "%";
    }
  }
  if (type === "move") {
    params.key += viewId;
  }

  const types = {
    add: "addUrl",
    del: "delUrl",
    move: "moveUrl",
  };
  const _params = {
    iframeOperationId: types[type], // 操作类型
    key: params.key, // 唯一id
    viewId: viewId,
    percentW, // 宽度百分比
    percentH, // 高度百分比
    percentX, // left百分比
    percentY, // top百分比
    only: new Date().getTime() + "" + randomFloat(),
  };
  if (type === "add") {
    _params.iframeSrc = params.src;
    _params.zIndex = 19;
    await iframeSDK({
      iframeOperationId: "delUrl",
      key: params.key, // 唯一id
    });
  }
  if (params.zIndex != null) {
    _params.zIndex = params.zIndex;
  }
  let returnData = null;
  if (type === "move" || type === "get") {
    _params.needBack = true;
    returnData = await iframeSDK({
      ..._params,
      only: new Date().getTime() + "" + randomFloat(),
    });
  } else {
    returnData = await iframeSDK(_params);
  }
  return new Promise((resolve) => {
    resolve(returnData);
  });
}

/**
 * 视频插件的postMessage
 */
export function videoPostMessage(param) {
  window.parent.postMessage(param, "*");
}

export function numberFix(val, p) {
  const num = parseFloat(val);
  if (num) {
    return num.toFixed(p || 2);
  }
  return "0.00";
}
export function numberAbs(val) {
  const num = parseFloat(val);
  if (num) {
    const abs = Math.abs(num);
    return abs == 100 ? "100" : abs.toFixed(2);
  }
  return "0.00";
}
/**
 * 动态处理根部font-size
 * @param {string} [direction='v' | 'h'] //- 'v' 竖屏 'h' 横
 */
export const setRootFontSize = (direction = "v") => {
  const htmlElement = document.documentElement;
  const viewportHeight = window.innerHeight;
  const baseHeight = direction === "v" ? 1080 : 1920;
  const referenceHeight = 1028;
  const newFontSize =
    direction === "v"
      ? `calc((100vh / ${baseHeight}) * 100 * (${baseHeight} / ${referenceHeight}))`
      : `calc((100vw / ${baseHeight}) * 100)`;

  htmlElement.style.fontSize = newFontSize;
};

export function clog(t) {
  console.log(
    `%c✨ ${t}`,
    "font-size:20px; background:#FFF; color:#581845;padding:10px; border: 3px solid #581845;border-radius:10px;"
  );
}

/**
 * 复制到剪切板
 * val: 要复制的参数
 */
export function copyToClipboard(val) {
  let aux = document.createElement("input");
  aux.value = val;
  document.body.appendChild(aux);
  aux.select();
  document.execCommand("copy");
  document.body.removeChild(aux);
  $message.s("复制成功");
}

// 3 判断多边形是否重合
export function isPolygonsOverlap(plyA, plyB) {
  const pointsA = formatPointList(plyA);
  const pointsB = formatPointList(plyB);
  return (
    isPolygonsIntersectant(pointsA, pointsB) ||
    isPointInPolygonBidirectional(pointsA, pointsB)
  );
}

function formatPointList(points) {
  let list = [];
  for (const point of points) {
    list.push([parseFloat(point.x), parseFloat(point.y)]);
  }
  return list;
}
